﻿using System;
using System.IO;
using System.Text.RegularExpressions;

namespace MediaController.Subs.Provider
{
    public class TitleFileInfo
    {
        protected string _filePath;

        public string FilePath
        {
            get { return _filePath; }
        }

        public TitleFileInfo TitleFileInfoByFolderName { get; set; }

        public string FileNameNoExt { get; set; }

        public string FolderName { get; set; }

        public string FolderPath { get; set; }

        public bool IsSeries { get; set; }

        public bool IsTwoCD { get; set; }

        public int CD { get; set; }

        public string TitleName { get; set; }

        public string Year { get; set; }

        public string Season { get; set; }

        public string Episode { get; set; }

        public ulong Size { get; set; }

        public bool IsHD { get; set; }

        public bool? FullHD { get; set; }

        public bool HasSubs { get; set; }

        protected TitleFileInfo()
        {

        }

        public TitleFileInfo(string filePath)
        {
            _filePath = filePath;
            if (filePath == null) throw new ArgumentNullException("filePath");

            if (!File.Exists(filePath)) throw new FileNotFoundException("Coludnt find file", filePath);

            ScanFile(this, filePath, true);
            TitleFileInfoByFolderName = new TitleFileInfo();

            ScanFile(TitleFileInfoByFolderName, filePath, false);
            TitleFileInfoByFolderName._filePath = filePath;
        }

        public override string ToString()
        {
            return FileNameNoExt;
        }

        #region Private Methods

        private void ScanFile(TitleFileInfo titleFileInfo, string filePath, bool parseByFileName)
        {
            var fileInfo = new FileInfo(filePath);

            titleFileInfo.FileNameNoExt = Path.GetFileNameWithoutExtension(filePath);
            titleFileInfo.FolderPath = fileInfo.DirectoryName;

            if (fileInfo.Directory != null)
                titleFileInfo.FolderName = fileInfo.Directory.Name;

            if (ParseIfTwoCD())
            {
                titleFileInfo.IsTwoCD = true;
                titleFileInfo.CD = ParseCD();
            }

            string parseString = parseByFileName ? FileNameNoExt : FolderName;

            titleFileInfo.TitleName = ParseMovieName(parseString);
            titleFileInfo.Year = ParseYear(parseString);
            if (ParseIfTV(parseString))
            {
                titleFileInfo.IsSeries = true;
                titleFileInfo.Season = ParseSeason(parseString);
                titleFileInfo.Episode = ParseEpisode(parseString);
            }

            ParseHD(titleFileInfo, parseString);
        }

        private void ParseHD(TitleFileInfo titleFileInfo, string parseString)
        {
            titleFileInfo.IsHD = parseString.ToLower().Contains("720p") || parseString.ToLower().Contains("1080p") ? true : false;

            if (titleFileInfo.IsHD && parseString.ToLower().Contains("1080p"))
                titleFileInfo.FullHD = true;
            else if (IsHD && parseString.ToLower().Contains("720p"))
                titleFileInfo.FullHD = false;
            else
                titleFileInfo.FullHD = null;

        }

        private string ParseYear(string stringToParse)
        {
            Match year = Regex.Match(stringToParse, "(?<=.)\\d\\d\\d\\d\\b");
            return year.Value;
        }

        private bool ParseIfTV(string stringToParse)
        {
            Match isTv = Regex.Match(stringToParse, @".*(?i)s\d{1,2}e\d{1,2}.*|.*(?i)s\d{1,2}.e\d{1,2}.*|\d{1,2}x\d{1,2}");
            return isTv.Success;
        }

        private string ParseSeason(string stringToParse)
        {
            Match season = Regex.Match(stringToParse, "(?i)(?<=s)\\d\\d(?=e\\d\\d)|\\d\\d(?=x\\d\\d)");
            return season.Value;
        }

        private string ParseEpisode(string stringToParse)
        {
            Match episode = Regex.Match(stringToParse, "(?i)(?<=s\\d\\de)\\d\\d|(?<=\\d\\dx)\\d\\d");
            return episode.Value;
        }

        private bool ParseIfTwoCD()
        {
            return FileNameNoExt.ToLower().Contains("cd1") || FileNameNoExt.ToLower().Contains("cd2") ||
                   FolderName.ToLower().Contains("cd1") || FolderName.ToLower().Contains("cd2");
        }

        private int ParseCD()
        {
            return FileNameNoExt.ToLower().Contains("cd1") || FolderName.ToLower().Contains("cd1") ? 1 : 2;
        }

        private string ParseMovieName(string stringToParse)
        {
            string movieName = Regex.Replace(stringToParse, "'", "");
            string clean = "576p|720p|1080p|1080i|dircut|directors cut|dvdrip|dvdscreener|dvdscr|avchd|wmv|ntsc|pal|mpeg|dsr|hd|r5|dvd|dvdr|dvd5|dvd9|bd5|bd9|dts|ac3|bluray|blu-ray|hdtv|pdtv|stv|hddvd|xvid|divx|x264|dxva|(?-i)FESTIVAL|LIMITED|WS|FS|PROPER|REPACK|RERIP|REAL|RETAIL|EXTENDED|REMASTERED|UNRATED|CHRONO|THEATRICAL|DC|SE|UNCUT|INTERNAL|DUBBED|SUBBED";
            movieName = Regex.Replace(movieName, clean, "");
            var match = Regex.Match(movieName, @"(?i-:(?<MediaName>.*?)\.S(\d){1,2}(\.){0,1}E(\d){1,2})", RegexOptions.IgnoreCase);
            if (match.Success)
            {
                movieName = match.Groups["MediaName"].Value;
            }
            else
            {
                var movieRexEx = @"^(?i-:(?<MediaName>.*?)\.(576p|720p|1080p|1080i|dircut|directors cut|dvdrip|dvdscreener|dvdscr|avchd|wmv|ntsc|pal|mpeg|dsr|hd|r5|dvd|dvdr|dvd5|dvd9|bd5|bd9|dts|ac3|bluray|blu-ray|hdtv|pdtv|stv|hddvd|xvid|divx|x264|dxva|(?-i)FESTIVAL|LIMITED|WS|FS|PROPER|REPACK|RERIP|REAL|RETAIL|EXTENDED|REMASTERED|UNRATED|CHRONO|THEATRICAL|DC|SE|UNCUT|INTERNAL|DUBBED|SUBBED|\d\d\d))";
                match = Regex.Match(movieName, movieRexEx, RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    movieName = match.Groups["MediaName"].Value;
                }
            }
            movieName = Regex.Replace(movieName, "\\.|,|-|_|\\(|\\)|:|&", " ");
            //Group name
            //movieName = Regex.Replace(movieName, "[a-zA-Z0-9]+$", " ");
            ////Scene
            //movieName = Regex.Replace(movieName, "\\b((?i)www|hebsub|horadot|repack|proper(?-i)|AUDIO|WS|DOCU|(?i)extended(.edition|.version|.cut)?(?-i)|(?i)directors(.edition|.version|.cut)?(?-i)|(?i)unrated(.edition|.version|.cut)?(?-i)|(?i)internal(.edition|.version|.cut)?(?-i)|(?i)limited(.edition|.version|.cut)?(?-i)|DUAL|MULTi|MULTI|COMPLETE)\\b", " ");
            ////Resolution
            //movieName = Regex.Replace(movieName, "(?i)\\b(pal|hdtv|pdtv|ntsc|720p|1080p)\\b", " ");
            ////Type
            //movieName = Regex.Replace(movieName, "(?i)\\b(us|cd\\d|stv|blu.?ray|blue.?ray|hd.?dvd|dvd5|dvd9|bd5|bd9|bd.?rip|brip|br.?rip|dvd.?rip|hdtv.?rip|hdtv)\\b", " ");
            ////Audio
            //movieName = Regex.Replace(movieName, "(?i)\\b(avc|lpcm|7.?1|vc.?1|ac.?3|5.?1|ma.?5.?1|hdma|dts(ma|.ma|hd|.hd)?|true.?hd|dolby)\\b", " ");
            ////Codec
            //movieName = Regex.Replace(movieName, "(?i)\\b(3d|divx|xvid|x264|h264|wmv|dxva|mpeg.?|ch)\\b", " ");
            ////Year
            //movieName = Regex.Replace(movieName, "(?<=.)\\d\\d\\d\\d\\b", " ");
            ////Punctuation marks
            //movieName = Regex.Replace(movieName, "\\.|,|-|_|\\(|\\)|:|&", " ");
            ////Remove Season & Episode
            //movieName = Regex.Replace(movieName, "(?i)s\\d\\de\\d\\d|\\d\\dx\\d\\d", " ");
            ////Remove spaces
            //movieName = Regex.Replace(movieName, "  +", " ");
            //movieName = Regex.Replace(movieName, "^[ \\t]+|[ \\t]+$", "");
            return movieName;
        }

        #endregion

    }
}